package com.gln.bloger.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import com.gln.bloger.constant.Constant;
import com.gln.bloger.exception.BlogerException;
import com.gln.bloger.log.Logging;
import com.gln.bloger.pojos.SiteConfig;
import com.gln.bloger.pojos.User;
import com.gln.bloger.pojos.Website;
import com.gln.bloger.service.CategoryService;
import com.gln.bloger.service.CommentService;
import com.gln.bloger.service.EntryService;
import com.gln.bloger.service.SearchService;
import com.gln.bloger.service.SiteConfigService;
import com.gln.bloger.service.TagService;
import com.gln.bloger.service.UserService;
import com.gln.bloger.service.WebsiteService;
import com.gln.bloger.util.StringUtil;

/**
 * Project's Struts Base Action Class Extend from Struts DispatchAction
 * 
 * @author LeoLeung Nicholas ren
 * Date: 2008/01/02
 */
public abstract class BaseAction extends DispatchAction {
	private UserService userService ;
	
	private CategoryService categoryService;
	
	private CommentService commentService;
	
	private EntryService entryService;
	
	private SearchService searchService;
	
	private TagService  tagService;
	
	private WebsiteService websiteService;
	
	private SiteConfigService siteConfigService;
	
	private String methodName;
	
	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}
	/**
	 * Override DispatchAction's excute method
	 */
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		/**
		 * Excute the doFirst method if return true, then continue next process
		 * else
		 */
		if (!this.doFirst(mapping, form, request, response)) {
		}

		ActionForward forward = null;

		try {
			prepareWebsite(request);
			prepareSiteConfig(request);
			forward = super.execute(mapping, form, request, response);

		}catch(BlogerException e){
			e.printStackTrace();
			forward = mapping.findForward(Constant.PAGE_500);
		}catch (Exception ex) {
			doWithException(ex);

			String parameter = this.getParameter(mapping, form, request,
					response);

			Logging.info(this.getClass()
					+ "'s [method]"
					+ this.getMethodName(mapping, form, request, response,
							parameter) + " End with Exception");
		}
		/**
		 * Execute the doLast method if return true, then continue next process
		 * else
		 */
		if (!this.doLast(mapping, form, request, response)) {
		}
		return forward;
	}

	/**
	 * Process before action's main process execute
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	protected boolean doFirst(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		String parameter = this.getParameter(mapping, form, request, response);
		this.methodName = this.getMethodName(mapping, form, request, response, parameter);
		

		Logging.info(this.getClass()
				+ "'s  [method]"
				+ methodName + " Start");
		return true;
	}

	/**
	 * Process after action's main process executed
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	protected boolean doLast(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		Logging.info(this.getClass()
				+ "'s  [method]"
				+ methodName + " End");
		return true;
	}

	/**
	 * Deal with Exception
	 * 
	 * @param t
	 */
	protected void doWithException(Throwable t) {
		t.printStackTrace();
		Logging.error(this, t);
	}

	/**
	 * get current web site
	 * @param request
	 * @throws Exception
	 */
	public Website getAuthWebsite(HttpServletRequest request) throws Exception{
		Website currentWebsite = (Website) request.getSession().
		                                   getAttribute(Constant.AUTH_WEBSITE);
	    return currentWebsite;
	}
	/**
	 * get current author
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public User getAuthUser(HttpServletRequest request) throws Exception{
		return (User) request.getSession().getAttribute(Constant.AUTH_USER);
	}
	
	private void prepareWebsite(HttpServletRequest request) throws Exception{
		String handle = (String) request.getParameter("handle");
		if(getAuthWebsite(request) == null && !StringUtil.isBlank(handle)){
			Website currentWebsite = getWebsiteService().getWebsite(handle);
			request.getSession().setAttribute(Constant.AUTH_WEBSITE, currentWebsite);
		}
	}
	
	private void prepareSiteConfig(HttpServletRequest request)throws Exception{
		
		SiteConfig siteConfig = (SiteConfig)request.getSession().
		                          getServletContext().getAttribute("siteConfig");
		if(siteConfig == null){
			siteConfig = this.getSiteConfigService().getSiteConfig();
			request.getSession().getServletContext().setAttribute("siteConfig", siteConfig);
		}
	}
	/**
	 * clear cached data;
	 */
	public void clearCache(){
		this.getCategoryService().clearCachedCategories();
		this.getCommentService().clearCachedRecentComments();
		this.getEntryService().clearCachedMonthList();
		this.getEntryService().clearCachedRecentEntries();
		this.getTagService().clearCachedHotTags();
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public CategoryService getCategoryService() {
		return categoryService;
	}

	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}

	public CommentService getCommentService() {
		return commentService;
	}

	public void setCommentService(CommentService commentService) {
		this.commentService = commentService;
	}

	public EntryService getEntryService() {
		return entryService;
	}

	public void setEntryService(EntryService entryService) {
		this.entryService = entryService;
	}

	public TagService getTagService() {
		return tagService;
	}

	public void setTagService(TagService tagService) {
		this.tagService = tagService;
	}

	public WebsiteService getWebsiteService() {
		return websiteService;
	}

	public void setWebsiteService(WebsiteService websiteService) {
		this.websiteService = websiteService;
	}

	public SearchService getSearchService() {
		return searchService;
	}

	public void setSearchService(SearchService searchService) {
		this.searchService = searchService;
	}
	public SiteConfigService getSiteConfigService() {
		return siteConfigService;
	}
	public void setSiteConfigService(SiteConfigService siteConfigService) {
		this.siteConfigService = siteConfigService;
	}
}